(function() {

    var
    $u = juliet.using({
        func : 'juliet.core.func-0.1',
        uidGenerator : 'juliet.core.uidGenerator-0.1',
        PopupHider : 'juliet.ui.popup.PopupHider'
    }),
    $ = juliet.jQuery;

    /**
     * Base class for popup controls.
     */
    var CustomPopupControlClass = function() {

        /**
         * Instance options (see inherited classes for details).
         *
         * @type Object
         * @private
         */
        this._options = null;

        /**
         * Is control visible?
         *
         * @type Boolean
         * @private
         */
        this._visible = false;

        /**
         * Control's uid. Uses in popup hider.
         *
         * @type String
         * @private
         */
        this._uid = null;

        /**
         * @see PopupHiderClass
         * @type Object
         * @private
         */
        this._popupHider = null;

        // -------------------------------------------------------
        // -                        LOGIC                        -
        // -------------------------------------------------------

        /**
         * @private
         */
        this._initializePopupHider = function() {
            this._popupHider = juliet.createObject($u('PopupHider'), this);
        };

        //
        // API
        //

        /**
         * Make popup control visible.
         */
        this.show = function() {
            throw 'Not implemented';
        };

        /**
         * Make popup control invisible.
         *
         * @param fromHider Method was called from popup hider.
         */
        this.hide = function(fromHider) {
            throw 'Not implemented';
        };

        /**
         * Used to prevent popup list from hiding by hider on bubble event phase
         * 'cause hider catches events on document level.
         *
         * @param {Function} callback After show callback function.
         */
        this.delayedShow = function(callback) {
            setTimeout($u('func').proxy(function() {
                this.show();
                if (callback) callback();
            }, this), 0);
        };

        /**
         * Initialize instance with specified options.
         *
         * @param {Object} o Instance options (see "_options" field for more details).
         */
        this.initialize = function(o) {
            this._options = o;
            this._uid = 'popup-' + $u('uidGenerator').getUid();
            this._initializePopupHider();
        };

        // -------------------------------------------------------
        // -                      GET & SET                      -
        // -------------------------------------------------------

        this.getUid = function() {
            return this._uid;
        };

        this.getOptions = function() {
            return this._options;
        };

        this.isVisible = function() {
            return this._visible;
        };

    };

    juliet.registerModule('juliet.ui.popup.control', 'CustomPopupControl-0.1', CustomPopupControlClass);

})();
